home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
appsrcs.zip
/
APPFINDR.ZIP
/
DFSERVER.C
< prev
next >
Wrap
Text File
|
1992-05-01
|
16KB
|
425 lines
/****************************************************************************
Module name: DFServer.C
Programmer : Jeffrey M. Richter.
Description: Drop File Server Sample Application.
*****************************************************************************/
#include <windows.h>
#include <shellapi.h>
#include <commdlg.h>
#include <string.h>
#include "DFServer.h"
//************ PROTOTYPES FOR FILE OPEN UTILITY FUNCTION ********************/
WORD FAR GetSinglePathName (LPCSTR szFileOpenStr, WORD wIndex,
LPSTR szPathName, WORD wMaxLen);
//************ PROTOTYPES FOR DROP-FILE SERVER FUNCTIONS ********************/
HDROP FAR DragCreateFiles (LPPOINT lpptMousePos, BOOL fInNonClientArea);
HDROP FAR DragAppendFile (HDROP hDrop, LPCSTR szPathname);
//****************** PROTOTYPES FOR LOCAL FUNCTIONS *************************/
LRESULT FAR WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
#define UM_UPDATECAPTION (WM_USER + 0) // wParam is number of files
//************************ GLOBAL VARIABLES *********************************/
char _szAppName[] = "Drop File Server";
extern _cdecl HINSTANCE _hInstance;
#pragma argsused
int WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow) {
MSG msg;
HWND hWnd;
WNDCLASS wc;
if (hPrevInstance == NULL) {
wc.style = 0;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = wc.cbWndExtra = 0;
_hInstance = wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, "DropFile");
wc.hCursor = LoadCursor(NULL, IDC_UPARROW);
wc.hbrBackground = COLOR_GRAYTEXT + 1;
wc.lpszMenuName = "DROPFILE";
wc.lpszClassName = _szAppName;
if (!RegisterClass(&wc)) return(0);
}
// Create the Frame window.
// The WS_EXACCEPTFILES style is not needed for server-only apps.
hWnd = CreateWindow(_szAppName, _szAppName,
WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME |
WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
CW_USEDEFAULT, nCmdShow,
GetSystemMetrics(SM_CXSCREEN) / 2, // 1/2-screen width
GetSystemMetrics(SM_CYSCREEN) / 8, // 1/8-screen height
NULL, NULL, hInstance, NULL);
if (hWnd == NULL) return(0);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}
LRESULT FAR WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
static char szAllFileNames[1000] = { 0 };
HCURSOR hCrsrDrpNotAllow, hCrsrDrpSingle, hCrsrDrpMultiple;
char szBuf[100], szDropPathName[200];
BOOL fCallDefProc = FALSE, fInNonClientArea, fOkToDrop;
LONG lResult = 0;
POINT ptMousePos;
WORD x, wNumFiles;
HWND hWndSubject;
HDROP hDrop, hDropT;
OPENFILENAME ofn;
switch (Msg) {
case WM_CREATE:
SendMessage(hWnd, UM_UPDATECAPTION, 0, 0);
break;
case WM_DESTROY:
// Terminate the application
PostQuitMessage(0);
break;
case WM_COMMAND:
if (wParam != IDM_FILESELECT) {
fCallDefProc = TRUE;
break;
}
// Initialize structure for calling
// the "Open File" common dialog
_fmemset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = "All files\0*.*\0";
ofn.Flags = OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST |
OFN_HIDEREADONLY;
// Set up the buffer to receive the selected file(s)
szAllFileNames[0] = 0;
ofn.lpstrFile = szAllFileNames;
ofn.nMaxFile = sizeof(szAllFileNames);
if (GetOpenFileName(&ofn))
wNumFiles = GetSinglePathName(szAllFileNames,
-1, NULL, 0);
else
wNumFiles = 0;
SendMessage(hWnd, UM_UPDATECAPTION, wNumFiles, 0);
break;
case UM_UPDATECAPTION:
// Update the window's caption to reflect the # of
// selected files
wsprintf(szBuf, "%s - %d file(s) to drop",
(LPSTR) _szAppName, wParam);
SetWindowText(hWnd, szBuf);
break;
case WM_LBUTTONDOWN:
// User has initiated the "Drag and Drop" sequence
// Make sure that there are some selected files
// to be dropped
wNumFiles = GetSinglePathName(szAllFileNames, -1,
NULL, 0);
if (wNumFiles == 0)
{
MessageBox(hWnd, "No files to drop.",
_szAppName, MB_OK);
break;
}
// Get the handles to the cursors that
// will shown to the user.
hCrsrDrpNotAllow = LoadCursor(_hInstance,
"DRPFIL_NOTALLOWED");
hCrsrDrpSingle = LoadCursor(_hInstance,
"DRPFIL_SINGLE");
hCrsrDrpMultiple = LoadCursor(_hInstance,
"DRPFIL_MULTIPLE");
// *** Loop for determining the drop-file
// client window ***
SetCapture(hWnd);
do {
// Get cursor pos. & window under the cursor
GetCursorPos(&ptMousePos);
hWndSubject = WindowFromPoint(ptMousePos);
if (!IsWindow(hWndSubject) ||
!(GetWindowLong(hWndSubject, GWL_EXSTYLE) &
WS_EX_ACCEPTFILES))
{
fOkToDrop = FALSE;
SetCursor(hCrsrDrpNotAllow);
}
else
{
fOkToDrop = TRUE;
SetCursor((wNumFiles > 1) ?
hCrsrDrpMultiple : hCrsrDrpSingle);
}
// Terminate loop when mouse button is released
} while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
ReleaseCapture();
// Free the loaded cursors from memory
DestroyCursor(hCrsrDrpNotAllow);
DestroyCursor(hCrsrDrpSingle);
DestroyCursor(hCrsrDrpMultiple);
if (!fOkToDrop) break;
// Is the cursor in the window's non-client area?
fInNonClientArea = (HTCLIENT !=
SendMessage(hWndSubject, WM_NCHITTEST, 0,
(LONG) MAKELONG(ptMousePos.x, ptMousePos.y)));
// Create drop-file memory block and initialize it
ScreenToClient(hWndSubject, &ptMousePos);
hDrop = DragCreateFiles(&ptMousePos, fInNonClientArea);
if (hDrop == NULL)
{
MessageBox(hWnd,
"Insufficient memory to drop file(s).",
_szAppName, MB_OK);
break;
}
// *** Append each full pathname to
// the drop-file memory block ***
for (x = 0; x < wNumFiles; x++)
{
GetSinglePathName(szAllFileNames, x,
szDropPathName, sizeof(szDropPathName));
// Append pathname to end of drop-file memory block
hDropT = DragAppendFile(hDrop, szDropPathName);
if (hDropT == NULL)
{
MessageBox(hWnd,
"Insufficient memory to drop file(s).",
_szAppName, MB_OK);
GlobalFree(hDrop);
hDrop = NULL;
break; // Terminate while loop
}
else
{
hDrop = hDropT;
}
}
if (hDrop != NULL)
{
// All pathnames appended successfully,
// post the message
// to the drop-file client window
PostMessage(hWndSubject, WM_DROPFILES, hDrop, 0L);
// Clear our own state
szAllFileNames[0] = 0;
SendMessage(hWnd, UM_UPDATECAPTION, 0, 0);
// Don't free the memory,
// the Dropfile client will do it
}
break;
default:
fCallDefProc = TRUE;
break;
}
if (fCallDefProc)
lResult = DefWindowProc(hWnd, Msg, wParam, lParam);
return(lResult);
}
/****************************************************************************/
/********************** **************************/
/********************** FILE OPEN UTILITY FUNCTION **************************/
/********************** **************************/
/****************************************************************************/
WORD FAR GetSinglePathName (LPCSTR szFileOpenStr, WORD wIndex,
LPSTR szPathName, WORD wMaxLen)
{
WORD wNumFiles = 0, x, y;
LPCSTR p = szFileOpenStr, q;
char szBuf[200];
// Initialize the buffer by clearing it
_fmemset(szBuf, 0, sizeof(szBuf));
// Calculate the number of files in szFileOpenStr
while (*p)
{
if (*p == ' ') wNumFiles++;
p++;
}
// If a single file was selected, there are no spaces but we
// should return that one file exists
if ((wNumFiles == 0) && (p != szFileOpenStr))
wNumFiles = 1;
// If the user only wants the number of files, return that
if ((int) wIndex == -1)
return(wNumFiles);
// User requested more files than exist
if (wIndex > wNumFiles)
return(0);
// *** Construct the full pathname of the requested string ***
if ((wIndex == 0) && (wNumFiles == 1))
{
_fstrncpy(szBuf, szFileOpenStr, wMaxLen);
}
else
{
// Copy the path portion of the string into a temp buffer
x = (WORD) ((p = _fstrchr(szFileOpenStr, ' ')) - szFileOpenStr);
_fstrncpy(szBuf, szFileOpenStr, x);
// Append a backslash if necessary
if (*(p - 1) != '\\')
{
szBuf[x] = '\\';
x++;
}
for (y = 0; y < wIndex; y++)
{
p++; // Increment past the space, 'p' points to proper filename
while (*p != ' ') p++;
}
p++; // Increment past the space, 'p' points to proper filename
// Find the end of the filename
q = _fstrchr(p, ' ');
if (q != NULL)
{
// Copy the filename into the temp buffer
_fstrncpy(&szBuf[x], p, (WORD) (q - p));
}
else
{
// Copy the filename (remainder of string) into the temp buffer
_fstrcpy(&szBuf[x], p);
}
}
if (szPathName != NULL)
{
// If the user passed an address, copy the string into its buffer
_fstrncpy(szPathName, szBuf, wMaxLen);
szPathName[wMaxLen - 1] = 0; // Force zero-termination
}
return(lstrlen(szBuf)); // Returns length of string
}
/****************************************************************************/
/********************** **************************/
/********************** DROP-FILE SERVER FUNCTIONS **************************/
/********************** **************************/
/****************************************************************************/
typedef struct {
WORD wSize; // Size of data structure
POINT ptMousePos; // Position of mouse cursor
BOOL fInNonClientArea; // Was the mouse in the
// window's non-client area
} DROPFILESTRUCT, FAR *LPDROPFILESTRUCT;
HDROP FAR DragCreateFiles (LPPOINT lpptMousePos,
BOOL fInNonClientArea)
{
HGLOBAL hDrop;
LPDROPFILESTRUCT lpDropFileStruct;
// GMEM_SHARE must be specified because the block will
// be passed to another application
hDrop = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(DROPFILESTRUCT) + 1);
// If unsuccessful, return NULL
if (hDrop == NULL) return(hDrop);
// Lock block and initialize the data members
lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
lpDropFileStruct->wSize = sizeof(DROPFILESTRUCT);
lpDropFileStruct->ptMousePos = *lpptMousePos;
lpDropFileStruct->fInNonClientArea = fInNonClientArea;
GlobalUnlock(hDrop);
return(hDrop);
}
HDROP FAR DragAppendFile (HGLOBAL hDrop, LPCSTR szPathname)
{
LPDROPFILESTRUCT lpDropFileStruct;
LPCSTR lpCrnt;
WORD wSize;
lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
// Point to first pathname in list
lpCrnt = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize;
// Search for a pathname were first byte is a zero byte
while (*lpCrnt) // While the 1st char of path is non-zero
{
while (*lpCrnt) lpCrnt++; // Skip to zero byte
lpCrnt++;
}
// Calculate current size of block
wSize = (WORD) (lpCrnt - (LPSTR) lpDropFileStruct + 1);
GlobalUnlock(hDrop);
// Increase block size to accommodate new pathname being appended
hDrop = GlobalReAlloc(hDrop, wSize + lstrlen(szPathname) + 1,
GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE);
// Return NULL if insufficient memory
if (hDrop == NULL) return(hDrop);
lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
// Append the pathname to the block
lstrcpy((LPSTR) lpDropFileStruct + wSize - 1, szPathname);
GlobalUnlock(hDrop);
return(hDrop); // Return the new handle to the block
}